/**
 * @file cm_message_converter.cpp
 * @author jmdvirus
 * @date 2021-11-30 10:08:31
 */

#include <memory>
#include <sstream>

#include "utils/cm_common.h"
#include "cm_message_converter.h"
#include "utils/cm_utils.h"

CMMessageConverterJson::CMMessageConverterJson() {}

CMMessageConverterJson::~CMMessageConverterJson() {}

int CMMessageConverterJson::load(const char *file)
{
    if (!file)
    {
        return -1;
    }
    char *data = NULL;
    int   len  = 0;
    int   ret  = cm_read_file_data(file, &data, &len);
    if (ret < 0)
    {
        return -2;
    }
    std::string d = data;
    ret           = load(d);
    if (data)
        cm_mem_free(data);
    return ret;
}

int CMMessageConverterJson::load(std::string &data)
{
    Json::CharReaderBuilder rbuilder;
    rbuilder["indentation"]   = "";
    rbuilder["precision"]     = 7;
    rbuilder["precisionType"] = "significant";
    std::string                             errs;
    std::unique_ptr<Json::CharReader> const reader(rbuilder.newCharReader());
    bool                                    ret = reader->parse(data.begin().base(), data.end().base(), &m_root, &errs);
    return ret && m_root.isObject() ? 0 : -2;
}

std::string CMMessageConverterJson::generateString()
{
    Json::StreamWriterBuilder wbuilder;
    wbuilder["indentation"]   = "";
    wbuilder["precision"]     = 7;
    wbuilder["precisionType"] = "significant";
    std::unique_ptr<Json::StreamWriter> writer(wbuilder.newStreamWriter());
    JSONCPP_OSTRINGSTREAM               sout;
    writer->write(m_root, &sout);
    return sout.str();
}

std::string CMMessageConverterJson::responseString(int code, char *msg)
{
    Json::Value r_root;
    r_root["code"] = code;
    r_root["msg"]  = msg;

    Json::StreamWriterBuilder wbuilder;
    wbuilder["indentation"]   = "";
    wbuilder["precision"]     = 7;
    wbuilder["precisionType"] = "significant";
    std::unique_ptr<Json::StreamWriter> writer(wbuilder.newStreamWriter());
    JSONCPP_OSTRINGSTREAM               sout;
    writer->write(r_root, &sout);

    return sout.str();
}

std::string CMMessageConverterJson::JsonValuetoString(Json::Value root)
{
    Json::StreamWriterBuilder           wbuilder;
    std::unique_ptr<Json::StreamWriter> writer(wbuilder.newStreamWriter());
    JSONCPP_OSTRINGSTREAM               sout;
    writer->write(root, &sout);

    return sout.str();
}

int CMMessageConverterJson::setString(const char *key1, const char *key2, const char *value)
{
    if (!key1)
    {
        return CM_E_ARGS;
    }
    if (key2 == NULL)
    {
        useRoot()[key1] = std::string((char*)value);
    }
    else
    {
        useRoot()[key1][key2] = std::string((char *)value);
    }
    return 0;
}

int CMMessageConverterJson::setInt(const char *key1, const char *key2, int value)
{
    if (!key1)
    {
        return CM_E_ARGS;
    }
    if (key2 == NULL)
    {
        useRoot()[key1] = value;
    }
    else
    {
        useRoot()[key1][key2] = value;
    }
    return 0;
}

int CMMessageConverterJson::setInt64(const char *key1, const char *key2, int64_t value)
{
    if (!key1)
    {
        return CM_E_ARGS;
    }
    if (key2 == NULL)
    {
        useRoot()[key1] = value;
    }
    else
    {
        useRoot()[key1][key2] = value;
    }
    return 0;
}

int CMMessageConverterJson::setDouble(const char *key1, const char *key2, double value)
{
    if (!key1)
    {
        return CM_E_ARGS;
    }
    if (key2 == NULL)
    {
        useRoot()[key1] = value;
    }
    else
    {
        useRoot()[key1][key2] = value;
    }
    return 0;
}

std::string CMMessageConverterJson::getString(const char *key1, const char *key2)
{
    if (!key1)
    {
        return "";
    }
    if (key2 == NULL)
    {
        if (useRoot()[key1].isString())
        {
            return useRoot()[key1].asString();
        }
    }
    else
    {
        if (useRoot()[key1][key2].isString())
        {
            return useRoot()[key1][key2].asString();
        }
    }
    return "";
}

int CMMessageConverterJson::getInt(const char *key1, const char *key2)
{
    if (!key1)
    {
        return CM_E_ARGS;
    }
    if (key2 == NULL)
    {
        if (useRoot()[key1].isInt())
        {
            return useRoot()[key1].asInt();
        }
    }
    else
    {
        if (useRoot()[key1][key2].isInt())
        {
            return useRoot()[key1][key2].asInt();
        }
    }
    return -2;
}

int64_t CMMessageConverterJson::getInt64(const char *key1, const char *key2)
{
    if (!key1)
    {
        return CM_E_ARGS;
    }
    if (key2 == NULL)
    {
        if (useRoot()[key1].isInt64())
        {
            return useRoot()[key1].asInt64();
        }
    }
    else
    {
        if (useRoot()[key1][key2].isInt64())
        {
            return useRoot()[key1][key2].asInt64();
        }
    }
    return -2;
}

double CMMessageConverterJson::getDouble(const char *key1, const char *key2)
{
    if (!key1)
    {
        return -1.0;
    }
    if (key2 == NULL)
    {
        if (useRoot()[key1].isDouble())
        {
            return useRoot()[key1].asDouble();
        }
    }
    else
    {
        if (useRoot()[key1][key2].isDouble())
        {
            return useRoot()[key1][key2].asDouble();
        }
    }
    return 0.0;
}
